home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / gui / ClassFree_src.lha / ClassFree_src / CFbuttonclass / class.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-25  |  11.6 KB  |  413 lines

  1. /* Sample class  for StormC*/
  2.  
  3. #include <clib/alib_protos.h>
  4. #include <proto/graphics.h>
  5. #include <proto/intuition.h>
  6. #include <proto/utility.h>
  7. #include <exec/libraries.h>
  8. #include <intuition/classes.h>
  9. #include <intuition/gadgetclass.h>
  10. #include <intuition/imageclass.h>
  11. #include <dos/dos.h>
  12. #include <string.h>
  13. #include "class.h"
  14. #include "CFbutton.h"
  15. #include "CFtexti.h"
  16. #ifdef DEBUG
  17.  #include "debug_protos.h"
  18.  extern APTR console;
  19. #endif
  20.  
  21. Class *initclass(struct classbase *base)
  22. {
  23.   Class *cl;
  24.  
  25.   if(cl = MakeClass(CFbuttonClassName,GADGETCLASS,NULL,
  26.         sizeof(struct objectdata),NULL))
  27.   {
  28.     cl->cl_Dispatcher.h_Entry = hookEntry;
  29.     cl->cl_Dispatcher.h_SubEntry = dispatcher;
  30.     AddClass(cl);
  31.   }
  32.   base->cl = cl;
  33.  
  34.   return(cl);
  35. }
  36.  
  37. BOOL removeclass(struct classbase *base)
  38. {
  39.   BOOL result;
  40.  
  41.   if(result = FreeClass(base->cl)) base->cl = NULL;
  42.  
  43.   return(result);
  44. }
  45.  
  46. ULONG dispatcher(Class *cl,Object *o,Msg msg)
  47. {
  48.   switch(msg->MethodID)
  49.   {
  50.     case OM_NEW:
  51.       return(newobject(cl,o,msg));
  52.     case OM_DISPOSE:
  53.       return(dispose(cl,o));
  54.     case OM_SET:
  55.       return(setattrs(cl,o,msg));
  56.     case GM_HITTEST:
  57.       return(GMR_GADGETHIT);
  58.     case GM_GOACTIVE:
  59.       return(goactive(cl,o,msg));
  60.     case GM_HANDLEINPUT:
  61.       return(handleinput(cl,o,msg));
  62.     case GM_GOINACTIVE:
  63.       return(goinactive(cl,o,msg));
  64.     case GM_RENDER:
  65.       return(render(cl,o,msg));
  66.     default:
  67.       return(DoSuperMethodA(cl,o,msg));
  68.   }
  69. }
  70.  
  71.  
  72. ULONG newobject(Class *cl,Object *o,Msg msg)
  73. {
  74.   ULONG newobj;
  75.   struct TagItem *intags = ((struct opSet *)msg)->ops_AttrList;
  76.   ULONG hgl,bor;
  77.   Tag filter[] = {GA_Highlight,GA_Border,TAG_DONE};
  78.  
  79.   /*  Filter out changed attributes */
  80.   hgl = GetTagData(GA_Highlight,TRUE,intags);
  81.   bor = GetTagData(GA_Border,TRUE,intags);
  82.   FilterTagItems(intags,filter,TAGFILTER_NOT);
  83.  
  84.   /* Create and init object */
  85.   if(newobj = DoSuperMethodA(cl,o,msg))
  86.   {
  87.     struct objectdata *dt = (struct objectdata *)INST_DATA(cl,newobj);
  88.     struct Gadget *btn = (struct Gadget *)newobj;
  89.  
  90.     dt->redo = TRUE;
  91.     dt->flags = NULL;
  92.     dt->layout = GetTagData(CFBU_Layout,NULL,intags);
  93.     if(bor) dt->flags |= F_BORDER;
  94.     if(hgl) dt->flags |= F_HIGHLITE;
  95.  
  96.     dt->border = (struct Image *)NewObject(NULL,FRAMEICLASS,
  97.             IA_Left, btn->LeftEdge, IA_Top, btn->TopEdge,
  98.             IA_Width, btn->Width, IA_Height, btn->Height,
  99.             IA_FrameType, FRAME_BUTTON,
  100.             IA_EdgesOnly, !hgl,
  101.             TAG_DONE);
  102.     dt->texti = (struct Image *)NewObject(NULL,CFtextiClassName,
  103.             IA_Left, btn->LeftEdge+2, IA_Top, 0,
  104.             IA_Width, btn->Width-4,
  105.             IA_Data, btn->GadgetText,
  106.             CFTI_PosFlags, dt->layout&(TIPOS_LEFT|TIPOS_RIGHT),
  107.             TAG_DONE);
  108.     if(!(dt->border&&dt->texti))
  109.     {
  110.       DoMethod((Object *)btn,OM_DISPOSE);
  111.       return(NULL);
  112.     }
  113.   }
  114.   return(newobj);
  115. }
  116.  
  117. ULONG dispose(Class *cl,Object *o)
  118. {
  119.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  120.  
  121.   DisposeObject(dt->border);
  122.   DisposeObject(dt->texti);
  123.   DoSuperMethod(cl,o,OM_DISPOSE);
  124.  
  125.   return(0);
  126. }
  127.  
  128. ULONG setattrs(Class *cl,Object *o,Msg msg)
  129. {
  130.   struct opSet *set = (struct opSet *)msg;
  131.   struct Gadget *btn = (struct Gadget *)o;
  132.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  133.   struct TagItem *intags = set->ops_AttrList;
  134.   ULONG hgl,bor;
  135.   Tag filter[] = {GA_Highlight,GA_Border,TAG_DONE};
  136.  
  137.   /*  Filter out changed attributes */
  138.   hgl = GetTagData(GA_Highlight,dt->flags&F_HIGHLITE,intags);
  139.   bor = GetTagData(GA_Border,dt->flags&F_BORDER,intags);
  140.   FilterTagItems(intags,filter,TAGFILTER_NOT);
  141.  
  142.   /* Set attributes */
  143.   DoSuperMethodA(cl,o,msg);
  144.   dt->redo = TRUE;
  145.   dt->layout = GetTagData(CFBU_Layout,dt->layout,intags);
  146.   if(bor)
  147.   {
  148.     dt->flags |= F_BORDER;
  149.     if(hgl) dt->flags |= F_HIGHLITE;
  150.   }
  151.   else dt->flags &= ~(F_BORDER|F_HIGHLITE);
  152.   DisposeObject(dt->border);
  153.   DisposeObject(dt->texti);
  154.   dt->border = (struct Image *)NewObject(NULL,FRAMEICLASS,
  155.           IA_Left, btn->LeftEdge, IA_Top, btn->TopEdge,
  156.           IA_Width, btn->Width, IA_Height, btn->Height,
  157.           IA_FrameType, FRAME_BUTTON,
  158.           IA_EdgesOnly, !hgl,
  159.           TAG_DONE);
  160.   dt->texti = (struct Image *)NewObject(NULL,CFtextiClassName,
  161.           IA_Left, btn->LeftEdge+2, IA_Top, 0,
  162.           IA_Width, btn->Width-4,
  163.           IA_Data, btn->GadgetText,
  164.           CFTI_PosFlags, dt->layout&(TIPOS_LEFT|TIPOS_RIGHT),
  165.           TAG_DONE);
  166.  
  167.   return(NULL);
  168. }
  169.  
  170.  
  171. ULONG goactive(Class *cl,Object *o,Msg msg)
  172. {
  173.   struct gpInput *input = (struct gpInput *)msg;
  174.   struct Gadget *btn = (struct Gadget *)o;
  175.   struct gpRender rend;
  176.  
  177.   if(btn->Activation&GACT_TOGGLESELECT)
  178.   {
  179.     if(btn->Flags&GFLG_SELECTED) btn->Flags &= ~GFLG_SELECTED;
  180.     else btn->Flags |= GFLG_SELECTED;
  181.   }
  182.   else btn->Flags |= GFLG_SELECTED;
  183.   rend.MethodID = GM_RENDER;
  184.   rend.gpr_GInfo = input->gpi_GInfo;
  185.   rend.gpr_RPort = ObtainGIRPort(input->gpi_GInfo);
  186.   rend.gpr_Redraw = GREDRAW_REDRAW;
  187.   render(cl,o,(Msg)&rend);
  188.   ReleaseGIRPort(rend.gpr_RPort);
  189.   if(btn->Activation&GACT_TOGGLESELECT) return(GMR_NOREUSE);
  190.   return(GMR_MEACTIVE);
  191. }
  192.  
  193. ULONG handleinput(Class *cl,Object *o,Msg msg)
  194. {
  195.   struct gpInput *input = (struct gpInput *)msg;
  196.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  197.   struct Gadget *btn = (struct Gadget *)o;
  198.   struct gpRender rend;
  199.   WORD mx = input->gpi_Mouse.X, my = input->gpi_Mouse.Y;
  200.   UWORD code;
  201.  
  202.   code = input->gpi_IEvent->ie_Code;
  203.   if(input->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
  204.   {
  205.     if(code == MENUDOWN) return(GMR_NOREUSE); /* Gadget Aborted */
  206.     if(mx<0||mx>btn->Width||my<0||my>btn->Height)
  207.     {
  208.       if(btn->Flags&GFLG_SELECTED)
  209.       {
  210.         btn->Flags &= ~GFLG_SELECTED;
  211.         rend.MethodID = GM_RENDER;
  212.         rend.gpr_GInfo = input->gpi_GInfo;
  213.         rend.gpr_Redraw = GREDRAW_REDRAW;
  214.         rend.gpr_RPort = ObtainGIRPort(input->gpi_GInfo);
  215.         render(cl,o,(Msg)&rend);
  216.         ReleaseGIRPort(rend.gpr_RPort);
  217.       }
  218.       if(code == SELECTUP) return(GMR_REUSE);
  219.          /* Gadget aborted, reuse event to send IDCMP_MOUSEBUTTONS. */
  220.     }
  221.     else
  222.     {
  223.       if(!(btn->Flags&GFLG_SELECTED))
  224.       {
  225.         btn->Flags |= GFLG_SELECTED;
  226.         rend.MethodID = GM_RENDER;
  227.         rend.gpr_GInfo = input->gpi_GInfo;
  228.         rend.gpr_Redraw = GREDRAW_REDRAW;
  229.         rend.gpr_RPort = ObtainGIRPort(input->gpi_GInfo);
  230.         render(cl,o,(Msg)&rend);
  231.         ReleaseGIRPort(rend.gpr_RPort);
  232.       }
  233.       if(code == SELECTUP)
  234.       {
  235.         if(btn->Activation&GACT_RELVERIFY)
  236.         {
  237.           *(input->gpi_Termination) = NULL; /* Hmmm.. */
  238.           return(GMR_NOREUSE|GMR_VERIFY);
  239.         }
  240.         else return(GMR_NOREUSE);
  241.       }
  242.     }
  243.   } /*  if(input->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE) */
  244.   if(input->gpi_IEvent->ie_Class == IECLASS_TIMER)
  245.   {
  246.     if(btn->Flags&GFLG_SELECTED)
  247.     {
  248.       struct opUpdate upd;
  249.       struct TagItem tag[2];
  250.  
  251.       upd.MethodID = OM_NOTIFY;
  252.       tag[0].ti_Tag = GA_ID; tag[0].ti_Data = btn->GadgetID;
  253.       tag[1].ti_Tag = TAG_DONE;
  254.       upd.opu_AttrList = tag;
  255.       upd.opu_GInfo = input->gpi_GInfo;
  256.       upd.opu_Flags = OPUF_INTERIM;
  257.       DoMethodA(o,(Msg)&upd);
  258.     }
  259.   } /* if(input->gpi_IEvent->ie_Class == IECLASS_TIMER) */
  260.  
  261.  
  262.   return(GMR_MEACTIVE);
  263. }
  264.  
  265. ULONG goinactive(Class *cl,Object *o,Msg msg)
  266. {
  267.   struct gpGoInactive *input = (struct gpGoInactive *)msg;
  268.   struct Gadget *btn = (struct Gadget *)o;
  269.   struct gpRender rend;
  270.   struct opUpdate upd;
  271.   struct TagItem tag[2];
  272.  
  273.  
  274.   if(btn->Flags&GFLG_SELECTED&&!(btn->Activation&GACT_TOGGLESELECT))
  275.   {
  276.     btn->Flags &= ~GFLG_SELECTED;
  277.     rend.MethodID = GM_RENDER;
  278.     rend.gpr_GInfo = input->gpgi_GInfo;
  279.     rend.gpr_RPort = ObtainGIRPort(input->gpgi_GInfo);
  280.     rend.gpr_Redraw = GREDRAW_REDRAW;
  281.     render(cl,o,(Msg)&rend);
  282.     ReleaseGIRPort(rend.gpr_RPort);
  283.     upd.MethodID = OM_NOTIFY;
  284.     tag[0].ti_Tag = GA_ID; tag[0].ti_Data = btn->GadgetID;
  285.     tag[1].ti_Tag = TAG_DONE;
  286.     upd.opu_AttrList = tag;
  287.     upd.opu_GInfo = input->gpgi_GInfo;
  288.     upd.opu_Flags = 0;
  289.     DoMethodA(o,(Msg)&upd);
  290.   }
  291.   return(NULL);
  292. }
  293.  
  294.  
  295. ULONG render(Class *cl,Object *o,Msg msg)
  296. {
  297.   struct gpRender *rend = (struct gpRender *)msg;
  298.   struct Gadget *btn = (struct Gadget *)o;
  299.   struct Image *img = (struct Image *)btn->GadgetRender;
  300.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  301.   struct RastPort *rp = rend->gpr_RPort;
  302.   struct opSet set;
  303.   struct impDraw draw;
  304.   struct TagItem tag[5];
  305.   UWORD *pens = rend->gpr_GInfo->gi_DrInfo->dri_Pens;
  306.  
  307.   if(dt->redo)
  308.   {
  309.     set.MethodID = OM_SET;
  310.     set.ops_AttrList = tag;
  311.     set.ops_GInfo = rend->gpr_GInfo;
  312.     tag[0].ti_Tag = IA_Left; tag[1].ti_Tag = IA_Top;
  313.     if(dt->layout&(LAYOUT_IMGABOVE|LAYOUT_IMGBELOW))
  314.     {
  315.       tag[2].ti_Tag = IA_Width; tag[2].ti_Data = btn->Width-4;
  316.       tag[0].ti_Data = btn->LeftEdge+2;
  317.       if(dt->layout&LAYOUT_IMGABOVE)
  318.       {
  319.         /* Compensation adjusted.. */
  320.         tag[1].ti_Data = btn->TopEdge+btn->Height-rp->TxHeight-2;
  321.         tag[3].ti_Tag = TAG_DONE;
  322.         DoMethodA((Object *)dt->texti,(Msg)&set);
  323.         tag[1].ti_Data = btn->TopEdge+1;
  324.       }
  325.       else
  326.       {
  327.         tag[1].ti_Data = btn->TopEdge+1;
  328.         tag[3].ti_Tag = TAG_DONE;
  329.         DoMethodA((Object *)dt->texti,(Msg)&set);
  330.         /* Compensation adjusted.. */
  331.         tag[1].ti_Data = btn->TopEdge+btn->Height-img->Height-1;
  332.       }
  333.       if(dt->layout&LAYOUT_IMGLEFT) ; /* Already set */
  334.       /* Note that subtracting img->Width fixes 1/one pixelbug */
  335.       else if(dt->layout&LAYOUT_IMGRIGHT) tag[0].ti_Data =
  336.           btn->LeftEdge+btn->Width-1-img->Width-1;
  337.       else tag[0].ti_Data = btn->LeftEdge + btn->Width/2 - img->Width/2;
  338.       tag[2].ti_Tag = TAG_DONE;
  339.       DoMethodA((Object *)img,(Msg)&set);
  340.     } /* if(dt->layout&(LAYOUT_IMGABOVE|LAYOUT_IMGBELOW) */
  341.     else if(dt->layout&(LAYOUT_IMGLEFT|LAYOUT_IMGRIGHT))
  342.     {
  343.       tag[2].ti_Tag = IA_Width;
  344.       tag[2].ti_Data = btn->Width-4-img->Width-2;
  345.       tag[1].ti_Data = btn->TopEdge + btn->Height/2 - (rp->TxHeight+1)/2;
  346.       if(dt->layout&LAYOUT_IMGLEFT)
  347.       {
  348.         /* Again the set width in tag[2] compensates for 1 pixelbug */
  349.         tag[0].ti_Data = btn->LeftEdge+img->Width+3;
  350.         tag[3].ti_Tag = TAG_DONE;
  351.         DoMethodA((Object *)dt->texti,(Msg)&set);
  352.         tag[0].ti_Data = btn->LeftEdge+2;
  353.       }
  354.       else
  355.       {
  356.         tag[0].ti_Data = btn->LeftEdge+3;
  357.         tag[3].ti_Tag = TAG_DONE;
  358.         DoMethodA((Object *)dt->texti,(Msg)&set);
  359.         /* Subtracting img->Width compensates for pixelbug */
  360.         tag[0].ti_Data = btn->LeftEdge+btn->Width-1-img->Width;
  361.       }
  362.       tag[1].ti_Data = btn->TopEdge + btn->Height/2 - img->Height/2;
  363.       tag[2].ti_Tag = TAG_DONE;
  364.       DoMethodA((Object *)img,(Msg)&set);
  365.     } /* else if(dt->layout&(LAYOUT_IMGLEFT|LAYOUT_IMGRIGHT) */
  366.     else
  367.     {
  368.       tag[0].ti_Tag = IA_Top;
  369.       tag[0].ti_Data = btn->TopEdge + (btn->Height+1)/2 - (rp->TxHeight+1)/2;
  370.       tag[1].ti_Tag = TAG_DONE;
  371.       DoMethodA((Object *)dt->texti,(Msg)&set);
  372.     }
  373.     dt->redo = FALSE;
  374.   }
  375.   /* Render gadget */
  376.   draw.MethodID = IM_DRAW;
  377.   draw.imp_RPort = rp;
  378.   draw.imp_Offset.X = 0; draw.imp_Offset.Y = 0;
  379.   if(btn->Flags&GFLG_SELECTED)
  380.   {
  381.     draw.imp_State = IDS_SELECTED;
  382.   }
  383.   else
  384.   {
  385.     draw.imp_State = IDS_NORMAL;
  386.   }
  387.   draw.imp_DrInfo = rend->gpr_GInfo->gi_DrInfo;
  388.   if(dt->flags&F_BORDER) DoMethodA((Object *)dt->border,(Msg)&draw);
  389.   if(btn->GadgetRender)
  390.   {
  391.     if(dt->layout&LAYOUT_IMGREL)
  392.     {
  393. #ifdef DEBUG
  394.   DLprintf(console,"\nLAYOUT_IMGREL flag\n");
  395. #endif
  396.       draw.imp_Offset.X = btn->LeftEdge; draw.imp_Offset.Y = btn->TopEdge;
  397.     }
  398.     DoMethodA((Object *)btn->GadgetRender,(Msg)&draw);
  399.   }
  400.   if(btn->Flags&GFLG_LABELSTRING)
  401.   {
  402.     /*
  403.        IDS_SLECTED state highlites CFtexti objects and if highlite
  404.        is not selected the button label should always be drawn
  405.        with IDS_NORMAL.
  406.     */
  407.     if(!(dt->flags&F_HIGHLITE)) draw.imp_State = IDS_NORMAL;
  408.     DoMethodA((Object *)dt->texti,(Msg)&draw);
  409.   }
  410.  
  411.   return(NULL);
  412. }
  413.